import screenfull from 'screenfull'
// import config from '@config'
import CryptoJS from 'crypto-js'
const config = window.Config
//bjbcsoft20220923
let cpk = btoa('n6Ü²\x87íÛM¶ÓÝ·')
const ret = {
    //AES 加密 ：字符串 key iv  返回base64
    Encrypt(word, keyStr, ivStr){
        let key = CryptoJS.enc.Utf8.parse(cpk)
        let iv = CryptoJS.enc.Utf8.parse(cpk)
        if (keyStr){
            key = CryptoJS.enc.Utf8.parse(keyStr)
            iv = CryptoJS.enc.Utf8.parse(ivStr)
        }
        const srcs = CryptoJS.enc.Utf8.parse(word)
        let encrypted = CryptoJS.AES.encrypt(srcs, key, {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        })
        return CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
    },
    /**
     * AES 解密 ：字符串 key iv  返回base64
     *
     */
    Decrypt(word, keyStr, ivStr){
        let key = CryptoJS.enc.Utf8.parse(cpk)
        let iv = CryptoJS.enc.Utf8.parse(cpk)
        if (keyStr){
            key = CryptoJS.enc.Utf8.parse(keyStr)
            iv = CryptoJS.enc.Utf8.parse(ivStr)
        }
        const base64 = CryptoJS.enc.Base64.parse(word)
        const src = CryptoJS.enc.Base64.stringify(base64)
        let decrypt = CryptoJS.AES.decrypt(src, key, {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        })
        let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
        return decryptedStr.toString()
    },
    /**
     * 数据计算  返回保留两位小数
     * arr要计算的数字数组
     * num保留几位小数
     * type-1加2减3乘4除
     */
    NumCalculation(arr, num, type){
        let cl = type == 1 ? 0 : 1;
        let cs = num ? num : 0;
        arr.forEach(val=>{
          if (type == 1){
            cl = cl + parseFloat(val);
          } else if (type == 3){
            cl = cl * parseFloat(val);
          }
        })
        return cl.toFixed(cs)
    },
    /**
 * 防抖 （多次触发只执行一次函数，delay 毫秒后才会执行，如果在delay 毫秒前又触发，则重新计时）
 * @param {Function} func 需要执行的函数
 * @param {number} delay 毫秒
 * @param {boolean} immediate true 会立即执行一次函数，然后再继续后面的逻辑 （多次触发只执行一次函数，delay 毫秒后才会执行，如果在delay 毫秒前又触发，则重新计时）
 * @return {*}
 */
    debounce(func, delay, immediate){
        let timer = null
        let debounced = function(){
            let context = this
            let args = arguments
            clearTimeout(timer)
            if (immediate){
                if (!timer){
                    func.apply(context, args)
                }
                timer = setTimeout(function(){
                    timer = null
                }, delay)
            } else {
                timer = setTimeout(function(){
                    func.apply(context, args)
                    timer = null
                }, delay)
            }
        }
        debounced.cancel = function(){
            clearTimeout(timer)
            timer = null
        }
        return debounced
    },
    /**
     * 深拷贝
     * @param {Object|Array} source
     * @returns {Object|Array}
     */
    deepClone(source){
        if (!source && typeof source !== 'object'){
            throw new Error('error arguments', 'deepClone')
        }
        let targetObj = source.constructor === Array ? [] : {}
        try {
            Object.keys(source).forEach(keys => {
                if (source[keys] && typeof source[keys] === 'object'){
                    targetObj[keys] = ret.deepClone(source[keys])
                } else {
                    targetObj[keys] = source[keys]
                }
            })
        } catch (error){
            targetObj = JSON.parse(JSON.stringify(source))
        }
        return targetObj
    },
    /**
     * 生产hash 默认16位
     * @param {String|Nulber} source
     * @returns {String}
     */
    createHash(hashLength = 16){
        if (!hashLength || typeof Number(hashLength) != 'number'){
            return
        }
        let ar = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
        let hs = []
        let hl = Number(hashLength)
        let al = ar.length
        for (let i = 0; i < hl; i++){
            hs.push(ar[Math.floor(Math.random() * al)])
        }

        return hs.join('')
    },
    /**
     *  数组去重 子项非对象的，单纯为数字，字符串的数组去重
     * @param {Array} arr
     * @return {Array}
     */
    unique(arr){
        let tmp = []
        for (let i = 0, len = arr.length; i < len; i++){
            if (tmp.indexOf(arr[i]) == -1){
                tmp.push(arr[i])
            }
        }
        return tmp
    },
    /**
     *  数组对象去重 根据对象key去重 value值相同即去重
     * @param {Array} arr  数组对象
     * @param {String} key key名
     * @return {Array} 新数组对象
     */
    reduceArr(arr, key){
        if (!arr || !arr.length){
            return arr
        }
        let reslut = []
        let obj = {}
        for (let i = 0; i < arr.length; i++){
            if (!obj[arr[i][key]]){
                reslut.push(arr[i])
                obj[arr[i][key]] = true
            }
        }
        return reslut
    },
    /**
     * 计算文件大小
     *
     * @param fileByte 文件字节
     */
    getFileSize(fileByte){
        let fileSize = 0
        if (fileByte < 1048576){
            fileSize = (fileByte / 1024).toFixed(2) + 'KB'
        } else if (fileByte == 1048576){
            fileSize = '1MB'
        } else if (fileByte > 1048576 && fileByte < 1073741824){
            fileSize = (fileByte / (1024 * 1024)).toFixed(2) + 'MB'
        } else if (fileByte == 1073741824){
            fileSize = '1GB'
        } else if (fileByte > 1073741824 && fileByte < 1099511627776){
            fileSize = (fileByte / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
        } else {
            fileSize = '文件超过1TB'
        }
        return fileSize
    },
    /**
     * 获取文件类型
     *
     * @param suffix 文件后缀名
     */
    getFileType(suffix){
        let accept = {
            doc: ['doc', 'docx', 'xls', 'xlsx', 'ppt'],
            pdf: ['pdf'],
            txt: ['txt'],
            img: ['jpg', 'jpeg', 'bmp', 'png', 'gif'],
            model: ['gim', 'udf', 'ugx']
        }
        let type = ''
        for (let k in accept){
            if (accept[k].indexOf(suffix) !== -1){
                type = k
                break
            }
        }
        return type
    },
    /**
     * 生成formData对象
     * * @param {data} object
     * @return {FormData}
     */
    formDataInit(data){
        const datas = new FormData()
        for (let k in data){
            if (typeof data[k] == 'string'){//前后去空格
                data[k] = data[k].replace(/^\s+/, '').replace(/\s+$/, '')
            }
            if (data[k] == 'null' || data[k] === null){
                datas.append[k] = ''
            } else if (k == 'files'){
                data[k].forEach(v => {
                    datas.append('files', v)
                })
            } else if (k != 'file' && k != 'udfFile' && typeof data[k] == 'object'){
                datas.append(k, JSON.stringify(data[k]))
            } else {
                datas.append(k, data[k] === 0 ? 0 : data[k] === false ? false : data[k] ? data[k] : '')
            }
        }
        return datas
    },
    /**
     * 全屏
     * * @param {fn}
     */
    screenFull(fn){
        if (screenfull.enabled){
            console.log('不支持全屏')
            return
        }
        if (screenfull.isFullscreen){//退出全屏
            screenfull.exit()
        }
        const midFn = function(){
            if (!screenfull.isFullscreen){
                screenfull.off('change', midFn)
            }
            fn && fn(screenfull.isFullscreen)
        }
        //全屏
        screenfull.request()
        screenfull.on('change', midFn)
    },
    /**
     * 窗口全屏
     * * @param {nodeId} 需要全屏的元素
     * * @param {fn} 回调 返回true  false
     */
    windowFull(nodeId, fn){
        const node = document.getElementById(nodeId)
        if (!node || node.className.indexOf('window-full') > -1){
            return
        }
        node.className = node.className + ' window-full'
        fn && fn(true)
        const exit = function(event){
            if (event.key == 'Escape'){
                ret.windowFullExit(nodeId)
                fn && fn(false)
                document.removeEventListener('keydown', exit)
            }
        }
        document.addEventListener('keydown', exit, false)
    },
    /**
     * 退出出窗口全屏
     * * @param {nodeId} 需要全屏的元素
     */
    windowFullExit(nodeId){
        const node = document.getElementById(nodeId)
        if (!node || node.className.indexOf('window-full') == -1){
            return
        }
        node.className = node.className.replace('window-full', '')
    },
    /**
     * 打开指定名称的弹窗
     */
    openPopup(url, windowName = 'uniquePopupWindow', type = '_blank', specs) {
      const filename = url.split('/').pop(); // 获取文件名
      const fileExtension = filename.split('.').pop(); // 获取文件扩展名
      console.log(fileExtension); // 输出: pdf
      if (fileExtension == 'pdf' || fileExtension == 'PDF'){
        if (!specs) {
          specs = "width=800,height=600,left=100,top=100,menubar=no,toolbar=no,resizable=yes,scrollbars=yes";
        }
        const openedWindow = window.open(url, windowName, specs);
        if (openedWindow) {
          openedWindow.focus();
        }
      } else {
        this.downFileIframe(url, null, windowName);
      }
    },
    /**
     * 关闭指定名称的弹窗
     */
    closePopup(windowName) {
      window.close(windowName);
    },
    downFileIframe(url, data, fileName){//文件下载通过iframe实现
        let iframe = document.createElement('iframe')
        const name = ret.createHash()
        iframe.name = fileName ? fileName : name
        iframe.style.position = 'fixed'
        iframe.style.left = '10000px'
        document.body.appendChild(iframe)
        let form = document.createElement('form')
        form.action = url
        form.method = data ? 'POST' : 'GET'
        // if (!config.downShow){//设置app.config.downShow = true 就可在下载报错的时候查看错误信息
        //     form.target = name
        // }
        if (data){
            for (let k in data){
                const input = document.createElement('input')
                input.name = k
                input.value = data[k] || ''
                form.appendChild(input)
            }
        }
        document.body.appendChild(form)
        form.submit()
        document.body.removeChild(form)
        setTimeout(()=>{
            document.body.removeChild(iframe)
        }, 1000 * 60 * 60)
        if (ret.notify){
            clearTimeout(ret.notify)
            ret.notify = null
        }
        // VM && VM.$notify({
        //     title: '下载中...',
        //     message: '请勿重复下载',
        //     duration: 1200
        // })
    }
}
export default ret
